在实际使用中经常遇见Scala <=> Java之间的转换。例如要调用某个第三方包的方法需要一个Java的Map,那么可能用到Scala提供的JavaConverters或JavaConversions工具包
案例:
//待转换的Map
scala> val m = Map(1->2)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
JavaConversions示例:
import collection.JavaConversions._
scala> val conversionsMap = mapAsJavaMap(m).asInstanceOf[java.util.Map[Int, Int]]
conversionsMap: java.util.Map[Int,Int] = {1=2}
JavaConversters示例:
import scala.collection.JavaConverters._
scala> val convertersMap = m.asJava
convertersMap: java.util.Map[Int,Int] = {1=2}
俩者都转换成功,看似一模一样的效果,为什么共同存在?
scala> conversionsMap.put(3,4)
java.lang.UnsupportedOperationException
at java.util.AbstractMap.put(AbstractMap.java:203)
... 33 elided
scala> convertersMap.put(3,4)
java.lang.UnsupportedOperationException
at java.util.AbstractMap.put(AbstractMap.java:203)
... 33 elided
转换成功后的Map竟然是不可修改的,这好像不符合我的需求,猜测是因为m是immutable类型的原因,那么继续:
//先转换成mutable
val m2 = collection.mutable.Map(m.toSeq: _*)
scala> m2.+(3->4)
res4: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
//好,现在m2可以修改了
scala> val conversionsMap = mapAsJavaMap(m2).asInstanceOf[java.util.Map[Int, Int]]
conversionsMap: java.util.Map[Int,Int] = {1=2}
scala> conversionsMap.put(3,4)
java.lang.UnsupportedOperationException
at java.util.AbstractMap.put(AbstractMap.java:203)
... 33 elided
//conversionsMap依旧不能修改,囧
scala> val convertersMap = m2.asJava
convertersMap: java.util.Map[Int,Int] = {1=2}
scala> convertersMap.put(3,4)
res5: Int = 0
scala> convertersMap
res6: java.util.Map[Int,Int] = {1=2, 3=4}
//convertersMap 可以修改
那么JavaConversions需要转换出可修改的Map该如何操作,搜索一番得到答案,JavaConversions提供的是Java集合之间的隐式转换,如果想让JavaConversions产出可变的Map应该如下操作:
//JavaConversions直接隐式的转换了
val conversionsMap2: java.util.Map[Int, Int] = m2
scala> conversionsMap2.put(3,4)
res7: Int = 0
scala> conversionsMap2
res8: java.util.Map[Int,Int] = {1=2, 3=4}
JavaConversions出现在V2.8版本,JavaConverters出现于V2.8.1,相比JavaConversions更新,并且显示的转换更易于理解,推荐使用JavaConverters